package com.springdemo.annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

@Aspect
@Component
public class LogAspect {
  @Pointcut("@annotation(com.springdemo.annotation.Log)")
  private void pointcut() {}

  @AfterReturning(returning="object",pointcut="pointcut()")
  public void insertLogSuccess(JoinPoint joinPoint,Object object) {
    System.out.println("执行SpringAOP日志后置增强");
    System.out.println("方法返回值："+object);
    addLog(joinPoint, getDesc(joinPoint));
  }
  private void addLog(JoinPoint joinPoint, String desc) {
    Log.LOG_TYPE type = getType(joinPoint);
    // 获取方法名字
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    if (requestAttributes != null) {
      // 用webContext获取到当前request对象
      HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
      // 用request获取IP
    } else {
      System.out.println("不存在request");
    }
    // 获取方法参数
    Object[] args = joinPoint.getArgs();
    StringBuffer stringBuffer = new StringBuffer();
    if (args != null) {
      for (Object arg : args) {
        // 参数拼接成字符串
        if (arg instanceof Model) {
          continue;
        }
        stringBuffer.append(arg + ",");
      }
    }
    MethodSignature signature = (MethodSignature)joinPoint.getSignature();
    Parameter[] parameters = signature.getMethod().getParameters();
    System.out.println("parameters:"+parameters[0]);
    System.out.println("参数是:"+stringBuffer.toString()+",日志类型："+type+",描述:"+desc);
  }

  /**
   * 切点中获取当前方法，总当前方法中获取注解和注解的属性
   * @param joinPoint
   * @return
   */
  private Log.LOG_TYPE getType(JoinPoint joinPoint) {
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    return method.getAnnotation(Log.class).type();
  }

  private String getDesc(JoinPoint joinPoint) {
    MethodSignature methodName = (MethodSignature) joinPoint.getSignature();
    Method method = methodName.getMethod();
    return method.getAnnotation(Log.class).desc();
  }
}
